package com.dily.study.springboot;

import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

/**
 * Date: 2022-07-04 星期一
 * Time: 10:47
 * Author: Dily_Su
 * Remark: 静态加载类
 */
public class DilySpringApplication {

    public static ConfigurableApplicationContext run(Class config) {
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(config);
        applicationContext.refresh();

        // spring boot 源码中 根据 pom.xml 中依赖 选择使用 tomcat / jetty / undertow, 默认使用 tomcat
        // 这里直接默认 tomcat
        startTomcat(applicationContext);

        return applicationContext;
    }

    /**
     * 创建 Tomcat 并启动
     * @param applicationContext spring 容器
     * @return Tomcat
     */
    private static Tomcat startTomcat(AnnotationConfigWebApplicationContext applicationContext) {
        // 创建和配置 Tomcat
        Tomcat tomcat = new Tomcat();

        Server server = tomcat.getServer();
        Service service = server.findService("Tomcat");

        Connector connector = new Connector();
        connector.setPort(8081);

        Engine engine = new StandardEngine();
        engine.setDefaultHost("localhost");

        Host host = new StandardHost();
        host.setName("localhost");

        String contextPath = "";
        Context context = new StandardContext();
        context.setPath(contextPath);
        context.addLifecycleListener(new Tomcat.FixContextListener());

        host.addChild(context);
        engine.addChild(host);

        service.setContainer(engine);
        service.addConnector(connector);

        // 从 IOC 容器中 获取 Spring Servlet
        DispatcherServlet defaultDispatcherServlet = applicationContext.getBean(DispatcherServlet.class);

        // 将获取到的 Spring servlet 加入到 tomcat 中
        tomcat.addServlet(contextPath, "dispatcher", defaultDispatcherServlet);
        context.addServletMappingDecoded("/*","dispatcher");

        try {
            // 启动 tomcat
            tomcat.start();
        }catch (LifecycleException e){
            e.printStackTrace();
        }

        return tomcat;
    }
}
